﻿using System;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.Threading;

namespace msTimer
{
    public partial class Form1 : Form
    {
        [DllImport("winmm")]
        static extern uint timeGetTime();

        [DllImport("winmm")]
        static extern void timeBeginPeriod(int t);

        [DllImport("winmm")]
        static extern uint timeEndPeriod(int t);

        ArrayList tmpArray = new ArrayList();
        //Thread timerthread;

        //Thread timerthread;

        public Form1()
        {
            InitializeComponent();
            Control.CheckForIllegalCrossThreadCalls = false;
            //Thread timerthread = new Thread(timer);
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            //
            //Thread timerthread = new Thread(timer);

            //timeBeginPeriod(1);

            //timerthread.Start();
        }


        private void timer()
        {
            uint timerstart = timeGetTime();
            while (true)
            {
                uint i = 0;
                while (i < 5)     //N为时间间隔（ms）
                {
                    i = timeGetTime() - timerstart;
                }
                timerstart = timeGetTime();
                timerfunction();               //需要循环运行的函数；           
            }
        }

        private void timerfunction()
        {
            
            tmpArray.Add( DateTime.Now.ToString("mm:ss:fff") );

        }

        private void button_start_Click(object sender, EventArgs e)
        {
            Thread timerthread = new Thread(timer);
            
            timeBeginPeriod(1);

            timerthread.Start();

            int i = 1;
            while( i< 5000){
                i++;
                if (i == 30) {
                    int t = 20;
                }
            }


            timerthread.Abort();

            timeEndPeriod(1);
        }

        private void button_stop_Click(object sender, EventArgs e)
        {
            this.Close();
        }
    }
}




/// <summary>
/// Pointer to a variable that receives the current performance-counter value, in counts.
/// </summary>
/// <param name="lpPerformanceCount"></param>
/// <returns>If the function succeeds, the return value is nonzero.
/// </returns>
[DllImport("Kernel32.dll")]
private static extern bool QueryPerformanceFrequency(out long lpPerformanceCount);

/// <summary>
/// Pointer to a variable that receives the current performance-counter frequency,
/// in counts per second.
/// If the installed hardware does not support a high-resolution performance counter,
/// this parameter can be zero.
/// </summary>
/// <param name="lpFrequency"></param>
/// <returns>If the installed hardware supports a high-resolution performance counter,
/// the return value is nonzero.
/// </returns>
[DllImport("Kernel32.dll")]
private static extern bool QueryPerformanceFrequency(out long lpFrequency);

另一篇就是介绍在C＃中使用这两个函数的方法了，也就是上面的代码。QueryPerformanceFrequency　函数是读取系统所支持的硬件定时器计数频率，也就是每秒的计数值，QueryPerformanceFrequency　应该是从开机时的计数值。这样通过读取两次计数值之差，再除以计数频率也就是两次读取时钟间隔的秒数。然后通过查询两次的间隔来确定是否响应服务函数，封装了如下类：
/// <summary> /// ManualTimer /// A simulated timer by loop /// It creates a new thread in Thread Pool using ThreadPool class /// Nocky Tian @ 2008-3-16 /// <remarks> /// The timer starts a new thread using <see cref="System.Threading.Thread"/> object, /// and the value of the property Priority is set to <seealso cref="System.Threading.ThreadPriority.Highest"/> /// so that the accuray could be kept 1ms around. /// /// </remarks> /// </summary> /// 
/// 
public class UltraHighAccurateTimer { 
    public event ManualTimerEventHandler tick; 
    private object threadLock = new object(); // for thread safe private long clockFrequency; 
    // result of QueryPerformanceFrequency() 
    bool running = true; 
    Thread thread ; 
    private int intervalMs; // interval in mimliseccond; 
    /// <summary> /// Timer inteval in milisecond /// </summary> 
    public int Interval { 
        get { return intervalMs; } 
        set { intervalMs = value; intevalTicks = (long)((double)value * (double)clockFrequency / (double)1000); } 
    } 
    private long intevalTicks; 
    private long nextTriggerTime; 
    // the time when next task will be executed /// <summary> /// Pointer to a variable that receives the current performance-counter value, in counts. /// </summary> /// <param name="lpPerformanceCount"></param> /// <returns>If the function succeeds, the return value is nonzero. /// </returns> 
    [DllImport("Kernel32.dll")] 
    private static extern bool QueryPerformanceCounter(out long lpPerformanceCount); /// <summary> /// Pointer to a variable that receives the current performance-counter frequency, /// in counts per second. /// If the installed hardware does not support a high-resolution performance counter, /// this parameter can be zero. /// </summary> /// <param name="lpFrequency"></param> /// <returns>If the installed hardware supports a high-resolution performance counter, /// the return value is nonzero. /// </returns> [DllImport("Kernel32.dll")] private static extern bool QueryPerformanceFrequency(out long lpFrequency); protected void OnTick() { if (tick != null) { tick(); } } public UltraHighAccurateTimer() { if (QueryPerformanceFrequency(out clockFrequency) == false) { // Frequency not supported throw new Win32Exception("QueryPerformanceFrequency() function is not supported"); } thread = new Thread(new ThreadStart(ThreadProc)); thread.Name = "HighAccuracyTimer"; thread.Priority = ThreadPriority.Highest; } /// <summary> /// 进程主程序 /// </summary> /// <param name="stateInfo"></param> private void ThreadProc() { long currTime; GetTick(out currTime); nextTriggerTime = currTime + intevalTicks; while (running) { while (currTime < nextTriggerTime) { GetTick(out currTime); } // wailt an interval nextTriggerTime = currTime + intevalTicks; //Console.WriteLine(DateTime.Now.ToString("ss.ffff")); if (tick != null) { tick(); } } } public bool GetTick(out long currentTickCount) { if (QueryPerformanceCounter(out currentTickCount) == false) throw new Win32Exception("QueryPerformanceCounter() failed!"); else return true; } public void Start() { thread.Start(); } public void Stop() { running = false; } ~UltraHighAccurateTimer() { running = false; thread.Abort(); } }